//
// OpenTemplate
// Copyright (c) 2006
// by OpenArrow Software ( http://www.openarrow.com )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using OpenArrow.Templating.Properties;

namespace OpenArrow.Templating.Directives
{
    /// <summary>
    /// Marks a class as a Directive that can be loaded from Template Source Files
    /// </summary>
    /// <remarks>
    /// <example language="C#">
    /// using OpenArrow.Templating.Directives;
    /// 
    /// // This directive should have the following form in an ASP.Net style template file
    /// // &lt;%@ MyDirectiveName MyProperty='MyValue' ... %&gt;
    /// [Directive("MyDirectiveName")]
    /// public class MyDirective : DirectiveBase
    /// {
    ///     // Implement DirectiveBase here by overriding PerformExecute
    ///     protected override void PerformExecute(DirectiveContext context)
    ///     {
    ///     }
    /// }
    /// </example>
    /// <example language="VB">
    /// Imports OpenArrow.Templating.Directives
    /// 
    /// ' This directive should have the following form in an ASP.Net style template file
    /// ' &lt;%@ MyDirectiveName MyProperty='MyValue' ... %&gt;
    /// &lt;Directive("MyDirectiveName")&gt; _
    /// Public Class MyDirective
    ///     Inherits DirectiveBase
    /// 
    ///     ' Implement DirectiveBase here by overriding PerformExecute
    ///     Protected Overrides Sub PerformExecute(ByVal context As DirectiveContext)
    ///     End Sub
    /// End Class
    /// </example>
    /// <example language="C++">Sorry, no C++ examples are available. Use the C# example as a basis.</example>
    /// </remarks>
    [AttributeUsage(AttributeTargets.Class)]
    public sealed class DirectiveAttribute : Attribute
    {
        private string directiveName;

        /// <summary>
        /// Gets or sets the name of the directive
        /// </summary>
        /// <remarks>
        /// The value of this property is used during parsing. In the <see cref="OpenArrow.Templating.Parsing.AspNetStyleTemplateParser"/>, 
        /// it is the text after the "&lt;%@" characters.
        /// </remarks>
        public string DirectiveName
        {
            get { return directiveName; }
        }

        /// <summary>
        /// Gets the directive name attached to the specified type, or <see langword="null" /> if there is no
        /// <see cref="DirectiveAttribute"/> attached to the type.
        /// </summary>
        /// <param name="type">The type to get the directive name for</param>
        /// <returns>
        /// The directive name attached to the specified type, or <see langword="null" /> if there is no
        /// <see cref="DirectiveAttribute"/> attached to the type.
        /// </returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
        public static string GetDirectiveName(Type type)
        {
            DirectiveAttribute tda = Attribute.GetCustomAttribute(type, typeof(DirectiveAttribute))
                as DirectiveAttribute;

            return tda == null ? null : tda.DirectiveName;
        }

        /// <summary>
        /// Constructs a new <see cref="DirectiveAttribute"/> object
        /// </summary>
        /// <param name="directiveName">The name of the directive</param>
        /// <remarks>
        /// <para>
        /// The value of the <paramref name="directiveName"/> parameter is used during parsing. In the 
        /// <see cref="OpenArrow.Templating.Parsing.AspNetStyleTemplateParser"/>, it is the text after the "&lt;%@" characters.
        /// </para>
        /// <para>Below is a short example on using <see cref="DirectiveAttribute"/></para>
        /// <example language="C#">
        /// using OpenArrow.Templating.Directives;
        /// 
        /// // This directive should have the following form in an ASP.Net style template file
        /// // &lt;%@ MyDirectiveName MyProperty='MyValue' ... %&gt;
        /// [Directive("MyDirectiveName")]
        /// public class MyDirective : DirectiveBase
        /// {
        ///     // Implement DirectiveBase here by overriding PerformExecute
        ///     protected override void PerformExecute(DirectiveContext context)
        ///     {
        ///     }
        /// }
        /// </example>
        /// <example language="VB">
        /// Imports OpenArrow.Templating.Directives
        /// 
        /// ' This directive should have the following form in an ASP.Net style template file
        /// ' &lt;%@ MyDirectiveName MyProperty='MyValue' ... %&gt;
        /// &lt;Directive("MyDirectiveName")&gt; _
        /// Public Class MyDirective
        ///     Inherits DirectiveBase
        /// 
        ///     ' Implement DirectiveBase here by overriding PerformExecute
        ///     Protected Overrides Sub PerformExecute(ByVal context As DirectiveContext)
        ///     End Sub
        /// End Class
        /// </example>
        /// <example language="C++">Sorry, no C++ examples are available. Use the C# example as a basis.</example>
        /// </remarks>
        /// <exception cref="ArgumentException"><paramref name="directiveName"/> is <see langword="null"/> or <see cref="String.Empty"/></exception>
        public DirectiveAttribute(string directiveName)
            : base()
        {
            if (String.IsNullOrEmpty(directiveName))
                throw new ArgumentException(String.Format(Resources.Exception_ArgIsNullOrEmpty, "directiveName"), "directiveName");

            this.directiveName = directiveName;
        }
    }
}
